package net.intellect.collectpro.objects;

import java.util.ArrayList;
import java.util.List;

import net.intellect.collectpro.util.Constantes;
import net.intellect.force.UtilBasic;

import com.sforce.soap.enterprise.ID;
import com.sforce.soap.enterprise.sobject.Agente_Mora__c;
import com.sforce.soap.enterprise.sobject.Agente_Producto__c;
import com.sforce.soap.enterprise.sobject.Agente__c;

public class Agente {
	private ID id = null;
	private ID idUser = null;
	private ID idSupervisor = null;
	private String name = "";
	private int cicloCobro = 0;
	private int maximoCobrosCiclo = 0;
	private int maximoCobrosDia = 0;
	private int minimoCobrosDia = 0;
	private int orden = 0;
	private int turno = 0;
	private int numGestionesPrevias = 0;
	private int numGestionesRebalse = 0; //Gestiones asignadas al agente por cobros de un mismo cliente en otra mora
		
	private List<ProductoAgente> productos 	  = new ArrayList<ProductoAgente>();
	private List<DiaAgente> diasCobro = new ArrayList<DiaAgente>();
	

	public Agente(ID id,ID idUser,ID idSupervisor,String name,int cicloCobro,int maximoCiclo,int maximoDiario,int minimoDiario,int orden,int turno,List<Agente_Producto__c> productosObj,List<Agente_Mora__c> morasObj) {
		this.id = id;
		this.idUser = idUser;
		this.idSupervisor = idSupervisor;
		this.name = name;
		this.cicloCobro = cicloCobro;
		this.maximoCobrosCiclo = maximoCiclo;
		this.maximoCobrosDia = maximoDiario;
		this.minimoCobrosDia = minimoDiario;
		this.orden = orden;
		this.turno = turno;
		
		if (productosObj!=null) {
			for (Agente_Producto__c productoObj:productosObj) {										
				ProductoAgente producto = new ProductoAgente(productoObj.getConf_Info_Producto__c(),productoObj.getConf_Info_Producto__r()!=null?productoObj.getConf_Info_Producto__r().getInfo_cuenta__c():null,productoObj.getMaximo_Gestiones__c());
				//Busca las moras
				if (morasObj!=null) {
					for (Agente_Mora__c moraObj:morasObj) {
						if (productoObj.getId()!=null && moraObj.getAgente_Producto__c()!=null && productoObj.getId().getID().equals(moraObj.getAgente_Producto__c().getID())) {
							MoraAgente mora = new MoraAgente(moraObj.getConf_Info_Mora__c());
							producto.getMoras().add(mora);
						}												
					}
				}								
				this.productos.add(producto);
			}
		}				
	}
	

	public List<ProductoAgente> getProductos() {
		return productos;
	}

	public void setProductos(List<ProductoAgente> productos) {
		this.productos = productos;
	}	
	
	public boolean equals(Object objeto) {
        if (!(objeto instanceof Agente || objeto instanceof Agente__c)) {
            return false;
        }
        if (((Agente__c) objeto).getId().getID().equalsIgnoreCase(this.getId().getID())) {
            return true;
        } else{
            return false;
        }		
	}
	
	public ID getId() {
		return id;
	}
	public void setId(ID id) {
		this.id = id;
	}
	
	public ID getIdUser() {
		return idUser;
	}
	public void setIdUser(ID idUser) {
		this.idUser = idUser;
	}

	public ID getIdSupervisor() {
		return idSupervisor;
	}
	public void setIdSupervisor(ID idSupervisor) {
		this.idSupervisor = idSupervisor;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public int getCicloCobro() {
		return cicloCobro;
	}
	public void setCicloCobro(int cicloCobro) {
		this.cicloCobro = cicloCobro;
	}

	public int getMaximoCobrosCiclo() {
		return maximoCobrosCiclo;
	}
	public void setMaximoCobrosCiclo(int maximoCobrosCiclo) {
		this.maximoCobrosCiclo = maximoCobrosCiclo;
	}

	public int getOrden() {
		return orden;
	}
	public void setOrden(int orden) {
		this.orden = orden;
	}

	public int getTurno() {
		return turno;
	}
	public void setTurno(int turno) {
		this.turno = turno;
	}
	

	public int getNumGestionesAsignadas() {
		int numCobrosAsignados = numGestionesPrevias + numGestionesRebalse;
		if (productos!=null && productos.size()>0) {
			for (ProductoAgente producto:productos) {					
				numCobrosAsignados+=producto.getGestiones();
			}
		}	
		return numCobrosAsignados;
	}
	
	public int getNumGestionesAsignadasCargaDiaria() {
		int numCobrosAsignados =  numGestionesRebalse;
		if (productos!=null && productos.size()>0) {
			for (ProductoAgente producto:productos) {					
				numCobrosAsignados+=producto.getGestiones();
			}
		}	
		return numCobrosAsignados;
	}	
	
	public boolean tieneCupoParaCobros(int numCobros) {
		if (this.getNumGestionesAsignadas()+numCobros<=maximoCobrosCiclo) {
			return true;
		} else {
			return false;
		}
	}
	
	public boolean cupoLlenoParaCobros() {
		if (this.getNumGestionesAsignadas()>=maximoCobrosCiclo) {
			return true;
		} else {
			return false;
		}
	}


	public List<DiaAgente> getDiasCobro() {
		return diasCobro;
	}


	public void setDiasCobro(List<DiaAgente> diasCobro) {
		this.diasCobro = diasCobro;
	}


	public int getMaximoCobrosDia() {
		return maximoCobrosDia;
	}


	public void setMaximoCobrosDia(int maximoCobrosDia) {
		this.maximoCobrosDia = maximoCobrosDia;
	}


	public int getMinimoCobrosDia() {
		return minimoCobrosDia;
	}


	public void setMinimoCobrosDia(int minimoCobrosDia) {
		this.minimoCobrosDia = minimoCobrosDia;
	}


	public int getNumGestionesPrevias() {
		return numGestionesPrevias;
	}


	public void setNumGestionesPrevias(int numGestionesPrevias) {
		this.numGestionesPrevias = numGestionesPrevias;
	}	
	
	public void distribuirCobrosPorProducto(List<Cobro> cobros) {			
		if (productos!=null && productos.size()>0) {
			for (Cobro cobro:cobros) {
				boolean asignadoAProducto = false;
				for (ProductoAgente producto:productos) {					
					if (producto.getIdProducto().getID().equals(cobro.getIdProducto().getID())) {							
						producto.addGestiones(1);
						asignadoAProducto = true;
						break;
					}
				}
				if (!asignadoAProducto) {
					this.numGestionesRebalse +=1;
				}
			}
		}	
	}
	
	public class ProductoAgente {
		private ID  idProducto = null;			
		private ID  idRecordTypeInfoCuenta = null;
		private int maximoGestiones = 0;
		private int gestiones = 0;
		List<MoraAgente> moras = new ArrayList<MoraAgente>();
		
		public ProductoAgente(ID idProducto,String idRecordTypeInfoCuenta,double maximoGestiones) {
			this.idProducto = idProducto;			
			this.idRecordTypeInfoCuenta = UtilBasic.obtenerId(idRecordTypeInfoCuenta);
			if (!Double.isNaN(maximoGestiones)) {
				this.maximoGestiones = (int)maximoGestiones;
			}
		}
		
		public int getMaximoGestiones() {
			return maximoGestiones;
		}
		public void setMaximoGestiones(int maximoGestiones) {
			this.maximoGestiones = maximoGestiones;
		}
		
		public int getGestiones() {
			return gestiones;
		}
		public void addGestiones(int newGestiones) {
			this.gestiones += newGestiones;
		}		

		public ID getIdProducto() {
			return idProducto;
		}

		public void setIdProducto(ID idProducto) {
			this.idProducto = idProducto;
		}

		public ID getIdRecordTypeInfoCuenta() {
			return idRecordTypeInfoCuenta;
		}

		public void setIdRecordTypeInfoCuenta(ID idRecordTypeInfoCuenta) {
			this.idRecordTypeInfoCuenta = idRecordTypeInfoCuenta;
		}
		
		public List<MoraAgente> getMoras() {
			return moras;
		}
		
		public void setMoras(List<MoraAgente> moras) {
			this.moras = moras;
		}
		
		public boolean tieneCupoProducto(int numCobros) {
			if (gestiones+numCobros<=maximoGestiones) {
				return true;
			} else {
				return false;
			}
		}
		
		
	}

	
	public class MoraAgente {
		private ID idMora = null;		
		
		public MoraAgente(ID idMora) {
			this.idMora = idMora;
		}
		
		public ID getIdMora() {
			return idMora;
		}
		public void setIdMora(ID idMora) {
			this.idMora = idMora;
		}
		
	}


	public int getNumGestionesRebalse() {
		return numGestionesRebalse;
	}


	public void setNumGestionesRebalse(int numGestionesRebalse) {
		this.numGestionesRebalse = numGestionesRebalse;
	}
	
	public boolean esAgenteCiclo(int ciclo) {
		if (this.cicloCobro==ciclo) return true;//Si son iguales devuelve verdadero
		if (cicloCobro>=Constantes.CICLO_60 && ciclo>=Constantes.CICLO_60) return true;
		return false;
	}
}
